package com.joker.dynamic.thread.pool.sdk.domain;

import com.joker.dynamic.thread.pool.sdk.domain.model.entity.ThreadPoolConfigEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 动态线程池服务
 * Created By guzq on 2024/10/19
 */
@Slf4j
public class DynamicThreadPoolService implements IDynamicThreadPoolService {

    private final Map<String, ThreadPoolExecutor> threadPoolExecutorMap;

    private final String applicationName;

    public DynamicThreadPoolService(Map<String, ThreadPoolExecutor> threadPoolExecutorMap, String applicationName) {
        this.threadPoolExecutorMap = threadPoolExecutorMap;
        this.applicationName = applicationName;
    }

    @Override
    public List<ThreadPoolConfigEntity> queryThreadPoolConfigList() {
        List<ThreadPoolConfigEntity> theadPoolConfigEntities = new ArrayList<>(threadPoolExecutorMap.keySet().size());
        for (String threadPoolName : threadPoolExecutorMap.keySet()) {
            ThreadPoolExecutor threadPoolExecutor = threadPoolExecutorMap.get(threadPoolName);
            ThreadPoolConfigEntity threadPoolConfigEntity = buildTheadPoolConfigEntity(threadPoolName, threadPoolExecutor);
            theadPoolConfigEntities.add(threadPoolConfigEntity);
        }
        return theadPoolConfigEntities;
    }

    @Override
    public ThreadPoolConfigEntity queryThreadPoolConfigByName(String threadPoolName) {
        if (StringUtils.isBlank(threadPoolName)) {
            ThreadPoolConfigEntity threadPoolConfigEntity = new ThreadPoolConfigEntity();
            threadPoolConfigEntity.setAppName(applicationName);
            return threadPoolConfigEntity;
        }

        ThreadPoolExecutor threadPoolExecutor = threadPoolExecutorMap.get(threadPoolName);

        return buildTheadPoolConfigEntity(threadPoolName, threadPoolExecutor);
    }


    @Override
    public void updateThreadPoolConfig(ThreadPoolConfigEntity threadPoolConfigEntity) {
        if (Objects.isNull(threadPoolConfigEntity)) {
            return;
        }

        ThreadPoolExecutor threadPoolExecutor = threadPoolExecutorMap.get(threadPoolConfigEntity.getThreadPoolName());
        if (Objects.isNull(threadPoolExecutor)) {
            return;
        }

        threadPoolExecutor.setCorePoolSize(threadPoolConfigEntity.getCorePoolSize());
        threadPoolExecutor.setMaximumPoolSize(threadPoolConfigEntity.getMaximumPoolSize());
    }

    private ThreadPoolConfigEntity buildTheadPoolConfigEntity(String threadPoolName, ThreadPoolExecutor threadPoolExecutor) {
        if (Objects.isNull(threadPoolExecutor)) {
            ThreadPoolConfigEntity threadPoolConfigEntity = new ThreadPoolConfigEntity();
            threadPoolConfigEntity.setAppName(applicationName);
            return threadPoolConfigEntity;
        }

        ThreadPoolConfigEntity threadPoolConfigEntity = new ThreadPoolConfigEntity();
        threadPoolConfigEntity.setAppName(applicationName);
        threadPoolConfigEntity.setThreadPoolName(threadPoolName);
        threadPoolConfigEntity.setCorePoolSize(threadPoolExecutor.getCorePoolSize());
        threadPoolConfigEntity.setMaximumPoolSize(threadPoolExecutor.getMaximumPoolSize());
        threadPoolConfigEntity.setActiveCount(threadPoolExecutor.getActiveCount());
        threadPoolConfigEntity.setPoolSize(threadPoolExecutor.getPoolSize());
        threadPoolConfigEntity.setQueueType(threadPoolExecutor.getQueue().getClass().getSimpleName());
        threadPoolConfigEntity.setQueueSize(threadPoolExecutor.getQueue().size());
        threadPoolConfigEntity.setQueueRemainingCapacity(threadPoolExecutor.getQueue().remainingCapacity());
        return threadPoolConfigEntity;
    }
}
